/******************************************************************************
*
* This file is part of FreeTrack (http://code.google.com/p/qtfreetrack).
* BY Willy Gardiol (willy@gardiol.org)
*
* FreeTrack is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FreeTrack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar.  If not, see <http://www.gnu.org/licenses/>
*
******************************************************************************/

#include "configfile.h"

ConfigFile::ConfigFile(const QString& file, QIODevice::OpenMode mode) :
    QObject(0),
    stream(NULL),
    filename(file),
    open_mode(QIODevice::NotOpen),
    device_file(NULL),
    status(false)
{
    device_file = new QFile( filename );

    if ( mode == QIODevice::ReadOnly )
    {
        if ( QFile::exists( file ) )
        {
            status = device_file->open( mode | QIODevice::Text);
            if ( status )
                open_mode = QIODevice::ReadOnly;
        }
    }
    else if ( mode == QIODevice::WriteOnly )
    {
        status = device_file->open( mode | QIODevice::Text);
        if ( status )
            open_mode = QIODevice::WriteOnly;
    }

    // start reading file
    if ( status )
        stream = new QTextStream(device_file);
}

ConfigFile::~ConfigFile()
{
    if ( device_file )
        delete device_file;
    if ( stream )
        delete stream;
}

bool ConfigFile::getStatus() const
{
    return status;
}

QString ConfigFile::getRawRow(const QString& w )
{
    if ( (status == false) ||
         (open_mode != QIODevice::ReadOnly ) )
        return "";

    QString what = w.toLower();
    // Check if it is already cached...
    if ( file_contents.contains( what ) )
        return file_contents[what];
    // No, read more of the file...
    QRegExp rx("^(\\S*)\\s*=\\s*(.*)$");
    bool found = false;
    QString var,val,row;

    while ( !stream->atEnd() && !found )
    {   // read line
        row = stream->readLine();
        if ( rx.indexIn(row) > -1 )
        {   // cache var/val pairs
            var = rx.cap(1).toLower();
            val = rx.cap(2);
            file_contents.insert( var, val );
            if ( var == what )
                found = true;
        }
    }
    return found ? file_contents[what] : "";
}

bool ConfigFile::readRow( const QString& row, QRegExp& rx )
{
    if ( (status == false) ||
         (open_mode != QIODevice::ReadOnly ) )
        return false;

    QString data = getRawRow( row );
    return rx.indexIn( data ) != -1;
}

QString ConfigFile::readRow(const QString& row)
{
    if ( (status == false) ||
         (open_mode != QIODevice::ReadOnly ) )
        return false;
    return getRawRow(row).trimmed();
}

bool ConfigFile::readRowBool(const QString& row)
{
    if ( (status == false) ||
         (open_mode != QIODevice::ReadOnly ) )
        return false;
    return getRawRow(row).trimmed().toLower() == "true";
}

bool ConfigFile::rowExists(const QString & row )
{
    if ( status == false )
        return false;
    else
        return getRawRow( row ) != "";
}

bool ConfigFile::writeRow( const QString& row, const QString& data)
{
    if ( (status == false) ||
         (open_mode != QIODevice::WriteOnly ) )
        return false;

    (*stream) << QString("%1 = %2\n").arg( row ).arg( data );
    return true;
}

bool ConfigFile::writeRow( const QString& row, const char* data)
{
    if ( (status == false) ||
         (open_mode != QIODevice::WriteOnly ) )
        return false;

    (*stream) << QString("%1 = %2\n").arg( row ).arg( data );
    return true;
}

bool ConfigFile::writeRow( const QString& row, bool data)
{
    if ( (status == false) ||
         (open_mode != QIODevice::WriteOnly ) )
        return false;

    (*stream) << QString("%1 = %2\n").arg( row ).arg( data ? "true" : "false" );
    return true;
}

bool ConfigFile::writeRow( const QString& row, int data)
{
    if ( (status == false) ||
         (open_mode != QIODevice::WriteOnly ) )
        return false;

    (*stream) << QString("%1 = %2\n").arg( row ).arg( data );
    return true;
}

bool ConfigFile::writeRow( const QString& row, double data)
{
    if ( (status == false) ||
         (open_mode != QIODevice::WriteOnly ) )
        return false;

    (*stream) << QString("%1 = %2\n").arg( row ).arg( data, 0, 'f', 14 );
    return true;
}
